package com.xcc.shopanim.utils;

import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import com.xcc.shopanim.BuildConfig;

import java.lang.reflect.Field;

/**
 * ****************************************************
 * 作者 :: rookieCi<1056907550@qq.com>
 * ----------------------------------------------------
 * git :: https://gitee.com/rookieci
 * ----------------------------------------------------
 * 博客 :: http://blog.csdn.net/xcccicishuai
 * ----------------------------------------------------
 * 时间 :: 2019/8/22 Add by rookieCi
 * ----------------------------------------------------
 * 描述 :: MemoryLeakUtil
 * ****************************************************
 */
public class MemoryLeakUtil {
    private static int SkipList;
    private static String[] viewArr = new String[]{"mCurRootView", "mServedView", "mNextServedView", "mLastSrvView"};

    /**
     * fix InputMethodManager leak memory
     *
     * @param context
     */
    public static void fixInputMethodMemoryLeak(Context context) {
        if (context == null)
            return;
        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputMethodManager == null)
            return;

        Field field;
        Object fieldObj;
        int skipIdx[] = new int[]{1, 2, 4, 8};
        for (int i = 0; i < viewArr.length; i++) {
            if ((SkipList & skipIdx[i]) > 0) continue;
            String view = viewArr[i];
            try {
                field = inputMethodManager.getClass().getDeclaredField(view);
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                fieldObj = field.get(inputMethodManager);
                if (fieldObj != null && fieldObj instanceof View) {
                    View fieldView = (View) fieldObj;
                    if (fieldView.getContext() == context) {// 被InputMethodManager持有引用的context是想要目标销毁的
                        field.set(inputMethodManager, null);
                    }
                }
            } catch (Exception e) {
                if (BuildConfig.DEBUG) e.printStackTrace();
                if (e instanceof NoSuchFieldException) {
                    SkipList = (SkipList | skipIdx[i]);
                }
            }
        }
    }
}
